package cn.iocoder.yudao.module.jifenyuan.service.roomuserbind;

import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.jifenyuan.convert.room.RoomConvert;
import cn.iocoder.yudao.module.jifenyuan.dal.dataobject.room.RoomDO;
import cn.iocoder.yudao.module.jifenyuan.dal.dataobject.room.RoomWithUsersDo;
import cn.iocoder.yudao.module.jifenyuan.dal.dataobject.roomuserbind.RoomUserBindWithInfoDO;
import cn.iocoder.yudao.module.jifenyuan.dal.mysql.room.RoomMapper;
import cn.iocoder.yudao.module.jifenyuan.enums.JifenyuanRoomStatusEnum;
import cn.iocoder.yudao.module.jifenyuan.enums.JifenyuanRoomUserTypeEnum;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.util.*;
import cn.iocoder.yudao.module.jifenyuan.controller.app.roomuserbind.vo.*;
import cn.iocoder.yudao.module.jifenyuan.dal.dataobject.roomuserbind.RoomUserBindDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;

import cn.iocoder.yudao.module.jifenyuan.convert.roomuserbind.RoomUserBindConvert;
import cn.iocoder.yudao.module.jifenyuan.dal.mysql.roomuserbind.RoomUserBindMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.jifenyuan.enums.ErrorCodeConstants.*;

/**
 * 记分员 房间与成员绑定 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class RoomUserBindServiceImpl implements RoomUserBindService {

    @Resource
    private RoomUserBindMapper roomUserBindMapper;
    @Resource
    private RoomMapper roomMapper;
    @Resource
    private MemberUserApi memberUserApi;

    @Override
    public Long createRoomUserBind(AppRoomUserBindCreateReqVO createReqVO) {
        // 插入
        RoomUserBindDO roomUserBind = RoomUserBindConvert.INSTANCE.convert(createReqVO);
        roomUserBindMapper.insert(roomUserBind);
        // 返回
        return roomUserBind.getId();
    }
    @Override
    public List<RoomUserBindWithInfoDO> getRoomDetail(Long roomId) {
        RoomDO roomDO = roomMapper.selectById(roomId);
        if(JifenyuanRoomStatusEnum.ENABLE.getStatus().equals(roomDO.getStatus())){
            //仍在开放中
            throw exception(ROOM_STILL_OPEN);
        }
        //获取房间内参与者
        List<RoomUserBindDO> roomUserBindDOs = roomUserBindMapper.selectRoomPartnerList(roomId);
        if(roomUserBindDOs!=null &&roomUserBindDOs.size()>0){
            List<RoomUserBindWithInfoDO> roomUserBindWithInfoDOS = RoomUserBindConvert.INSTANCE.convertList03(roomUserBindDOs);
            HashSet<Long> userIds = new HashSet<>();
            for (RoomUserBindWithInfoDO roomUserBindWithInfoDO : roomUserBindWithInfoDOS) {
                userIds.add(roomUserBindWithInfoDO.getUserId());
            }
            List<Long> userIdList = new ArrayList<>();
            userIdList.addAll(userIds);
            List<MemberUserRespDTO> users = memberUserApi.getUsers(userIdList);
            for (RoomUserBindWithInfoDO roomUserBindWithInfoDO : roomUserBindWithInfoDOS) {
                MemberUserRespDTO fromUserRespDTO = users.stream().filter(i -> i.getId().equals(roomUserBindWithInfoDO.getUserId())).findFirst().orElse(null);
                if(fromUserRespDTO!=null){
                    roomUserBindWithInfoDO.setNickname(fromUserRespDTO.getNickname());
                    roomUserBindWithInfoDO.setAvatar(fromUserRespDTO.getAvatar());
                }

            }
            return roomUserBindWithInfoDOS;
        }
        return null;
    }

    @Override
    public void updateRoomUserBind(AppRoomUserBindUpdateReqVO updateReqVO) {
        // 校验存在
        validateRoomUserBindExists(updateReqVO.getId());
        // 更新
        RoomUserBindDO updateObj = RoomUserBindConvert.INSTANCE.convert(updateReqVO);
        roomUserBindMapper.updateById(updateObj);
    }

    @Override
    public int addScore(Long roomId, Long userId, Long score) {
        return roomUserBindMapper.addScore(roomId,userId,score);
    }

    @Override
    public int reduceScore(Long roomId, Long userId, Long score) {
        return roomUserBindMapper.reduceScore(roomId,userId,score);
    }

    @Override
    public void deleteRoomUserBind(Long id) {
        // 校验存在
        validateRoomUserBindExists(id);
        // 删除
        roomUserBindMapper.deleteById(id);
    }

    private void validateRoomUserBindExists(Long id) {
        if (roomUserBindMapper.selectById(id) == null) {
            throw exception(ROOM_USER_BIND_NOT_EXISTS);
        }
    }

    @Override
    public RoomUserBindDO getRoomUserBind(Long id) {
        return roomUserBindMapper.selectById(id);
    }

    @Override
    public List<RoomUserBindDO> getRoomUserBindList(Collection<Long> ids) {
        return roomUserBindMapper.selectBatchIds(ids);
    }

    @Override
    public Long getCountByUserId(){
       return roomUserBindMapper.selectCount(RoomUserBindDO::getUserId,SecurityFrameworkUtils.getLoginUserId());

    }
    @Override
    public PageResult<RoomWithUsersDo> getRoomUserBindPage(AppRoomUserBindPageReqVO pageReqVO) {
        pageReqVO.setUserId(SecurityFrameworkUtils.getLoginUserId());
        pageReqVO.setType(JifenyuanRoomUserTypeEnum.PARTNER.getStatus());
        PageResult<RoomUserBindDO> roomUserBindDOPageResult = roomUserBindMapper.selectPage(pageReqVO);
            List<RoomWithUsersDo> result = new ArrayList<>();
        for (RoomUserBindDO roomUserBindDO : roomUserBindDOPageResult.getList()) {
            RoomDO roomDO = roomMapper.selectOne(RoomDO::getId, roomUserBindDO.getRoomId());
            RoomWithUsersDo room  = RoomConvert.INSTANCE.convert2(roomDO);
            List<RoomUserBindDO> roomUserBindDOS = roomUserBindMapper.selectRoomPartnerList(roomUserBindDO.getRoomId());
            List<RoomUserBindWithInfoDO> roomUserBindWithInfoDOS = RoomUserBindConvert.INSTANCE.convertList03(roomUserBindDOS);
            HashSet<Long> userIds = new HashSet<>();
            for (RoomUserBindWithInfoDO roomUserBindWithInfoDO : roomUserBindWithInfoDOS) {
                userIds.add(roomUserBindWithInfoDO.getUserId());
            }
            List<Long> userIdList = new ArrayList<>();
            userIdList.addAll(userIds);
            List<MemberUserRespDTO> users = memberUserApi.getUsers(userIdList);
            for (RoomUserBindWithInfoDO roomUserBindWithInfoDO : roomUserBindWithInfoDOS) {
                MemberUserRespDTO fromUserRespDTO = users.stream().filter(i -> i.getId().equals(roomUserBindWithInfoDO.getUserId())).findFirst().orElse(null);
                if(fromUserRespDTO!=null){
                    roomUserBindWithInfoDO.setNickname(fromUserRespDTO.getNickname());
                    roomUserBindWithInfoDO.setAvatar(fromUserRespDTO.getAvatar());
                }

            }
            room.setPartners(roomUserBindWithInfoDOS);
            result.add(room);
        }
        PageResult<RoomWithUsersDo> pageResult = new PageResult();
        pageResult.setTotal(roomUserBindDOPageResult.getTotal());
        pageResult.setList(result);

        return pageResult;
    }

    @Override
    public List<RoomUserBindDO> getRoomUserBindList(AppRoomUserBindExportReqVO exportReqVO) {
        return roomUserBindMapper.selectList(exportReqVO);
    }

}
